package nku.csc460;

import java.net.*;
import java.io.*;

class fooserver extends Thread{
	//Server fields
	ServerSocket MyService = null;
    public static Socket serviceSocketArray[] = new Socket[4];
    public final int maxConnections = 4;
    public static Integer currentClient = 0;

    //Game and Client Stuff 
    public static String clientNames[] = new String[4];
    public static Integer clientScores[] = new Integer[4];
    public static Integer maxQuestion = 0;
    public static Boolean finishFlag[] = new Boolean[4];
    public static Game gameInstance = new Game();
    public static Integer questionNumber[] = new Integer[4];			
    
    //Instance Methods
    Socket mySocket = null;
    int myClientNumber;
    BufferedReader input = null;
    PrintWriter output = null;
    
    	
    //Server Constructor		
    public fooserver() 
    {
    	startServer();
    	for(int i = 0; i < maxConnections; i++){
    		clientScores[i] = 0;
    		finishFlag[i] = false;
    		questionNumber[i] = 11;
    	}
    }
    
    public fooserver(Socket clientSocket, int socketNumber){
    	mySocket = clientSocket;
    	myClientNumber = socketNumber;
    	this.input = this.openInputStream(mySocket);
    	this.output = this.openOutputStream(mySocket);
    }
    
    //Main Method
    public static void main(String... Args)
    {
		fooserver gameServer = new fooserver();
		fooserver gameServerClients[] = new fooserver[4];
    	for(int i = 0; i < gameServer.maxConnections; i++)
    	{
    		if(gameServer.maxQuestion > 8){
    			break;
    		}
			serviceSocketArray[i] = gameServer.waitForConnection(); 
			gameServerClients[i] = new fooserver(serviceSocketArray[i], i);
			currentClient++;
			gameServerClients[i].start();
    	}
    	
    	
    }
    
    public void run(){
    	clientNames[myClientNumber] = this.readLine(input);
		Integer i = this.maxQuestion;
		this.sendMessage(output, i.toString());
		for(; i < 10; i++){
			fooserver.questionNumber[myClientNumber] = i;
			if(fooserver.maxQuestion < i){
				fooserver.maxQuestion = i;
			}
			String answer = null;
			int questionScore = 0;
			String correctAnswer = null;
			
			for(int j = 0; j < currentClient; j++){
				while(true){
					if(fooserver.questionNumber[myClientNumber] <= fooserver.questionNumber[j])
					{	
						break;
					}
				}		
			}
			
			this.sendMessage(output, gameInstance.getQuestionAndAnswerChoices(i));
			answer = this.readLine(input);
			questionScore = gameInstance.getScore(i, answer);
			clientScores[myClientNumber] += questionScore;
			this.sendMessage(output, "The In-Correct Answer is: " + gameInstance.getInCorrectAnswer(i));
	  		this.sendMessage(output, "Your score for the question is: " + questionScore);
			this.sendMessage(output, "Your Current Score is: " + clientScores[myClientNumber]);
			
		}
		fooserver.finishFlag[myClientNumber] = true;

		for(int j = 0; j < currentClient; j++){
			while(true){
				if(fooserver.finishFlag[j] == true)
				{	
					break;
				}
			}
					
		}
		
		this.sendMessage(output, "Game Over!!");
		this.sendMessage(output, "You " + this.won(myClientNumber) + "!");
		String place = this.checkPlace(myClientNumber);
		this.sendMessage(output, "Your " + place + "!");
		this.sendMessage(output, "Your final score is: " + clientScores[myClientNumber]);
		this.sendMessage(output, this.standings());
    }
    
    //Open a server socket
    public void startServer(){
    	try{
			MyService = new ServerSocket(8241);
			System.out.println("Started the server! ");
		}
		catch(IOException e){
			System.out.println(e);
			System.out.println("Starting the server failed! ");
			System.exit(1);
		}
    }
    
    //Wait for connection
    public Socket waitForConnection(){
    	Socket serviceSocket = null;
    	try{
			serviceSocket = MyService.accept();
			System.out.println("I have recieved a connection! ");
		}
		catch(IOException e){
			System.out.println(e);
			System.out.println("Recieving a connection failed! ");
			System.exit(1);
		}
		
		return serviceSocket;
    }
    
    
    //Open an input stream with a specific socket
    public BufferedReader openInputStream(Socket socket){
    	try{
			DataInputStream inputStream = new DataInputStream(socket.getInputStream());
			BufferedReader input = new BufferedReader(new InputStreamReader(inputStream));
			System.out.println("The input stream is opened to recieve messages from client!");
			return input;
		}
		catch(IOException e){
			System.out.println(e);
			System.out.println("Failed to open an input stream to recieve messages from client!");
			System.exit(1);
		}
		return null;
    }
    
    //Open an output stream with a specific socket
    public PrintWriter openOutputStream(Socket socket){
		try 
		{
			PrintWriter output = new PrintWriter(socket.getOutputStream());
			System.out.println("The output stream is opened to send messages to client!");
			return output;  
		}
		catch(IOException e){
			System.out.println(e);
			System.out.println("Failed to open stream to send messages to client!");
			System.exit(1);
		}
		return null;
    }
    
    //sendmessages at a give print writer
    public void sendMessage(PrintWriter output, String... lines){
    	for(String line: lines)
    	{
    		output.println(line);
    	}
    	output.flush();
    }
    
    
    //readline specified buffered reader
    public String readLine(BufferedReader input){
    	String line = null;
    	try
    	{
    		line = input.readLine();	
		}
		catch(IOException e)
		{
			System.out.println(e);
			System.out.println("Communication Failed!");
			System.exit(1);
		}
		return line;
    }    

	
	public String won(int clientNumber){
    	int myScore = this.clientScores[clientNumber];
    	for(int i = 0; i < this.currentClient; i++){
    		if(myScore < this.clientScores[i]){
    			return "Lost!";
    		}
    	}
    	return "Won!";
    }
    
    public String checkPlace(int clientNumber){
    	int myScore = this.clientScores[clientNumber];
    	int tempPlace = 1;
    	for(int i = 0; i < this.currentClient; i++){
    		if(myScore < this.clientScores[i]){
    			tempPlace++;
    		}
    	}
    	if(tempPlace == 1){
    		return "First";
    	}
    	else if(tempPlace == 2){
    		return "Second";
    	}
    	else if(tempPlace == 3) {
    		return "Third";
    	}
    	else if (tempPlace == 4) {
    		return "Fourth";
    	}
    	else{
    		return "Something is fucked!";
    	}
    	
    }
    
    public String[] standings(){
    	String standingsArray[] = new String[4];
    	Integer tempScores[] = new Integer[this.currentClient];
    	for(int i = 0; i < this.currentClient; i++){
    		tempScores[i] = this.clientScores[i];
    	}
    	
    	for(int i = 0; i < this.currentClient; i++){
    		int highValue  = -2501;
    		int key = -1;
    		for(int j = 0; j < this.currentClient; j++){
    			if(highValue < tempScores[j]){
    				highValue = tempScores[j];
    				key = i;
    			}
    		}
    		tempScores[key] = -2502;
    		standingsArray[i] = this.clientNames[key] + " has a score of " + this.clientScores[key];
    	}
    	
    	for(int i = this.currentClient; i < 4 ; i++){
    		standingsArray[i] = "No Client, So no score!";
    	}
    	return standingsArray;
    }
}

class Game{
	String inCorrectAnswers[] = new String[10];
	String questions[] = new String[10];
	String option1[] = new String[10];
	String option2[] = new String[10];
	String option3[] = new String[10];
	String option4[] = new String[10];
	
	Game(){
		BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in));
		String filename = null;
		try{
			System.out.print("Enter a filename: ");
			filename = commandLine.readLine();
		}
		catch(IOException e)
		{
			System.out.println(e);
			System.out.println("Cannot read file name!");
			System.out.println("If you can't enter a correct file name you won't continue i will crash!");
			System.exit(1);
		}
		try{
			FileReader fr = new FileReader(filename);
			BufferedReader brFile = new BufferedReader(fr);
			for(int i = 0; i < 10; i++){
				questions[i] = brFile.readLine();
				option1[i] = brFile.readLine();
				option2[i] = brFile.readLine();
				option3[i] = brFile.readLine();
				option4[i] = brFile.readLine();
				inCorrectAnswers[i] = brFile.readLine();
			}
		}
		catch(IOException e){
			System.out.println(e);
			System.out.println("Error Reading File! ");
			System.exit(1);
		}
		
	}
	
	public String[] getQuestionAndAnswerChoices(int i){
		String temp[] = new String [5];
		temp[0] = questions[i];
		temp[1] = option1[i];
		temp[2] = option2[i];
		temp[3] = option3[i];
		temp[4] = option4[i];
		return temp;
	}
	
	public int getScore(int i, String answer){
		if(answer.contains(inCorrectAnswers[i])){
			return -250;
		}
		else{
			return 250*answer.length();
		}
	}
	
	public String getInCorrectAnswer(int i){
		return inCorrectAnswers[i];
	}
	
}